package cachestring

import (
	"sync"
	"time"
	"willow/common/sdk"
)

type WList struct {
	Length  int64		//列表的长度
	Head	*listNode	//头结点
	Trail	*listNode	//尾杰点
}

type listNode struct {
	prev	*listNode	//前置节点
	next	*listNode	//后置节点
	val		*listVal		//list的值
}

type listVal struct {
	value []byte
	setTime    int64	//创建字符串的时间
	outTime    int64      //过期时间
}

var once     sync.Once
var listMap  map[string]WList

func init()  {
	once.Do(func() {
		listMap = make(map[string]WList)
	})
}

func (wlist *WList)ListInit() {
	once.Do(func() {
		wlist = &WList{
			Length: 0,
			Head:   &listNode{},
			Trail:  &listNode{},
		}
	})
}

/**
 * 将一个值插入到列表头部
 */
func (wlist *WList)LPush(listName string,listValue string) int64 {
	if list , ok := listMap[listName];ok {
		list.Length++
		newList 	:= &listNode{
			prev: nil,
			next: list.Head,
			val:  &listVal{
				value:   []byte(listValue),
				setTime: time.Now().UnixNano(),
				outTime: timeOut,
			},
		}

		newList.next.prev 	= newList
		list.Head 			= newList
		listMap[listName] 	= list
		return list.Length
	} else {
		newList		:= &listNode{
			prev: nil,
			next: nil,
			val:  &listVal{
				value:   []byte(listValue),
				setTime: time.Now().UnixNano(),
				outTime: 0,
			},
		}
		listMap[listName] = WList{
			Length: 1,
			Head:   newList,
			Trail:  newList,
		}
		return 1
	}
	return -1
}

func (wlist *WList)BLPop(listName string) interface{} {
	if list,ok := listMap[listName] ; ok {
		if list.Length > 1 {
			list.Length--
			tmp := list.Head.val.value
			list.Head = list.Head.next
			list.Head.prev = nil
			listMap[listName] = list
			return sdk.ByteString(tmp)
		} else if list.Length == 1 {
			list.Length--
			tmp := list.Head.val.value
			list.Head = nil
			list.Trail = nil
			listMap[listName] = list
			return sdk.ByteString(tmp)
		}
	}
	return nil
}

func (wlist *WList)BRPop(listName string) interface{} {
	if list,ok := listMap[listName] ; ok {
		if list.Length > 1 {
			list.Length--
			tmp := list.Trail.val.value
			list.Trail = list.Trail.prev
			list.Trail.next = nil
			listMap[listName] = list
			return sdk.ByteString(tmp)
		} else if list.Length == 1 {
			list.Length--
			tmp := list.Head.val.value
			list.Head = nil
			list.Trail = nil
			listMap[listName] = list
			return sdk.ByteString(tmp)
		}
	}
	return nil
}





